package com.mtw.bbs.message.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mtw.bbs.article.feign.ArticleClient;
import com.mtw.bbs.common.core.constant.MessageConstant;
import com.mtw.bbs.common.core.constant.SysConstant;
import com.mtw.bbs.common.core.vo.Result;
import com.mtw.bbs.message.mapper.MessageMapper;
import com.mtw.bbs.message.pojo.entity.Message;
import com.mtw.bbs.message.pojo.entity.MessageExtend;
import com.mtw.bbs.message.pojo.vo.MessageExtendVo;
import com.mtw.bbs.message.pojo.vo.MessageVo;
import com.mtw.bbs.message.service.MessageExtendService;
import com.mtw.bbs.message.service.MessageService;
import com.mtw.bbs.userAdmin.feign.UserClient;
import com.mtw.bbs.userAdmin.pojo.vo.UserInfoVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import static com.mtw.bbs.message.constant.MsgConstant.MSG_LIKE_LOCK;

/**
 * 消息逻辑层
 */
@Slf4j
@RequiredArgsConstructor
@Service("commentFileService")
public  class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {



    private final UserClient userClient;
    private final ArticleClient articleClient;
    private final RedissonClient redissonClient;
    private final MessageExtendService messageExtendService;


    /**
     * 分页获取消息
     *
     * @param page         当前页
     * @param size         分页大小
     * @param qw           查询条件
     * @return             分页结果
     */
    @Override
    public Page<MessageVo> getMessagVoPage(int page, int size, QueryWrapper<Message> qw) {


        Page<Message> entityPage = page(new Page<>(page, size), qw);
        Page<MessageVo> voPge = new Page<>();
        BeanUtils.copyProperties(entityPage,voPge);
        voPge.setRecords(new ArrayList<>(entityPage.getRecords().size()));

        if (entityPage.getRecords().isEmpty()){
            return voPge;
        }


        HashSet<String> senderIds = new HashSet<>(size);
        // 点赞或评论的文章
        HashSet<String> articleIds = new HashSet<>(size);
        // 点赞或评论的评论
        HashSet<String> commentIds = new HashSet<>(size);

        entityPage.getRecords().forEach(x->{
            if (MessageConstant.MSG_LIKE_ARTICLE.equals(x.getType())){
                articleIds.add(x.getBillId());
            }
            if (MessageConstant.MSG_COMMENT_ARTICLE.equals(x.getType())){
                articleIds.add(x.getBillParentId());
                commentIds.add(x.getBillId());
            }
            if (MessageConstant.MSG_LIKE_COMMENT.equals(x.getType())){
                commentIds.add(x.getBillId());
            }
            if (MessageConstant.MSG_COMMENT_COMMENT.equals(x.getType())){
                commentIds.add(x.getBillParentId());
                commentIds.add(x.getBillId());
            }
            senderIds.add(x.getCreatedBy());
        });

        // 获取用户信息
        HashMap<String, UserInfoVo> userMap = new HashMap<>(size);
        if (!senderIds.isEmpty()){
//            Result<List<UserDto>> listResult = userClient.userinfoByIds(senderIds.toArray(String[]::new));
//            if (listResult.isSuccess() && listResult.getData() != null){
//                for (UserDto x : listResult.getData()) {
//                    userMap.put(x.getId(),x.toVO());
//                }
//            }
        }

        // 获取文章信息
//        HashMap<String, SimpleArticleDto> articleMap = new HashMap<>(size);
//        if (!articleIds.isEmpty()){
//            Result<List<SimpleArticleDto>> result = articleClient.getSimpleArticle(articleIds.toArray(String[]::new));
//            if (result.isSuccess() && result.getData() != null){
//                for (SimpleArticleDto x : result.getData()) {
//                    articleMap.put(x.getId(),x);
//                }
//            }
//        }

        // 获取评论信息
//        HashMap<String, SimpleCommentDto> commentMap = new HashMap<>(size);
//        if (!commentIds.isEmpty()){
//            Result<List<SimpleCommentDto>> simpleComment = commentClient.getSimpleComment(new ArrayList<>(commentIds));
//            if (simpleComment.isSuccess() && simpleComment.getData() != null){
//                for (SimpleCommentDto x : simpleComment.getData()) {
//                    commentMap.put(x.getId(),x);
//                }
//            }
//        }

        entityPage.getRecords().forEach(x->{
            MessageVo vo = new MessageVo();
            BeanUtils.copyProperties(x,vo);

            // 文章的点赞
//            if (MessageConstant.MSG_LIKE_ARTICLE.equals(x.getType())){
//                vo.setArticle(articleMap.get(x.getBillId()));
//            }
//            // 文章的评论
//            if (MessageConstant.MSG_COMMENT_ARTICLE.equals(x.getType())){
//                vo.setArticle(articleMap.get(x.getBillParentId()));
//            }
            // 评论点赞、评论的评论、文章的评论
//            if (MessageConstant.MSG_LIKE_COMMENT.equals(x.getType()) || MessageConstant.MSG_COMMENT_COMMENT.equals(x.getType())
//                    || MessageConstant.MSG_COMMENT_ARTICLE.equals(x.getType())){
//                vo.setComment(commentMap.get(x.getBillId()));
//            }
//            // 评论的评论
//            if (MessageConstant.MSG_COMMENT_COMMENT.equals(x.getType()) ){
//                vo.setParentComment(commentMap.get(x.getBillParentId()));
//            }

            if (Boolean.TRUE.equals(x.getExtend()) && (MessageConstant.MSG_LIKE_ARTICLE.equals(x.getType()) || MessageConstant.MSG_LIKE_COMMENT.equals(x.getType()))){
                if (StringUtils.isBlank(x.getCreatedBy())){
                    Page<MessageExtendVo> messagExtendVoPage = messageExtendService.getMessagExtendVoPage(1, 5, x.getId());
                    vo.setExtendCount(messagExtendVoPage.getTotal());
                    vo.setExtend(messagExtendVoPage.getRecords());
                }
            }

            vo.setSenderInfo(userMap.get(x.getCreatedBy()));
            voPge.getRecords().add(vo);
        });
        return voPge;
    }


    /**
     * 新增消息
     * @param message
     * @return
     */
    @Override
    @Transactional
    public boolean saveMessage(Message message) {


        if (MessageConstant.MSG_LIKE_ARTICLE.equals(message.getType()) || MessageConstant.MSG_LIKE_COMMENT.equals(message.getType())){
            String key = MSG_LIKE_LOCK + message.getType() + "_"+  message.getBillId();
            RLock lock = redissonClient.getLock(key);
            lock.lock();
            try {
                LambdaQueryWrapper<Message> qw = new LambdaQueryWrapper<>();
                qw.eq(Message::getBillId,message.getBillId());
                qw.eq(Message::getType,message.getType());
                qw.eq(Message::getReceiver,message.getReceiver());
                Message had = getOne(qw);
                // 已存在点赞消息
                if (had != null){
                    // 新增扩展
                    MessageExtend extend = new MessageExtend();
                    BeanUtils.copyProperties(message,extend);
                    extend.setMsgId(had.getId());
                    messageExtendService.save(extend);
                    // 设为未读
                    had.setReadStatus(0);
                    updateById(had);
                    return true;
                }else {
                    return save(message);
                }
            }finally {
                lock.unlock();
            }
        }
        return save(message);
    }


    /**
     * 消息已读
     * @param message
     * @return
     */
    @Override
    public boolean readMessage(Message message) {
        LambdaUpdateWrapper<Message> luw = new LambdaUpdateWrapper<>();
        luw.set(Message::getReadStatus, SysConstant.DEFAULT_TRUE);
        luw.eq(Message::getId,message.getId());
        luw.eq(Message::getReceiver,message.getReceiver());
        return update(luw);
    }


    /**
     * 删除消息
     * @param message
     * @return
     */
    @Override
    public boolean deleteMessage(Message message) {
        LambdaQueryWrapper<Message> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Message::getId,message.getId());
        lqw.eq(Message::getReceiver,message.getReceiver());
        return remove(lqw);
    }
}
